﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;

namespace Draco.OWF.Repository
{
    public interface IPackageHeader
    {
        string Version { get; set; }
        Dictionary<String, String> NamedTypes { get; }
        void Serialize(XmlElement parent);
        void Deserialize(XmlElement parent);
        void RegisterNamedType(String name,String type);
        String getRegistedType(String name);
    }
    public class PackageHeader : IPackageHeader
    {
        private String m_Version;
        private Dictionary<String, String> m_NamedTypes = new Dictionary<string,string>();

        public string Version { get { return m_Version; } set { if(!String.IsNullOrEmpty(value)) m_Version=value;} }
        public Dictionary<String, String> NamedTypes { get { return m_NamedTypes; } }

        public PackageHeader()
        {
            m_Version = "1.0";
        }

        public void Serialize(XmlElement parent)
        {
            if (parent == null)
                throw new ArgumentNullException();
            XmlElement xmlPackageHeader = parent.OwnerDocument.CreateElement("PackageHeader");
            parent.InsertBefore(xmlPackageHeader, parent.FirstChild);

            XmlAttribute attrVer = parent.OwnerDocument.CreateAttribute("Ver");
            attrVer.Value = this.Version;
            xmlPackageHeader.Attributes.Append(attrVer);

            if (this.NamedTypes.Count > 0)
            {
                XmlElement xmlNamedTypes = parent.OwnerDocument.CreateElement("NamedTypes");
                foreach (var dict in NamedTypes)
                {
                    XmlElement xmlNamedType = parent.OwnerDocument.CreateElement("Type");
                    XmlAttribute attrName = parent.OwnerDocument.CreateAttribute("Name");
                    attrName.Value = dict.Key;
                    xmlNamedType.Attributes.Append(attrName);

                    xmlNamedType.InnerText = dict.Value;

                    xmlNamedTypes.AppendChild(xmlNamedType);
                }
                xmlPackageHeader.AppendChild(xmlNamedTypes);
            }
        }

        public void Deserialize(XmlElement parent)
        {
            if (parent == null)
                throw new ArgumentNullException();
            XmlElement xmlPackageHeader = null;
            if (parent.LocalName == "PackageHeader")
                xmlPackageHeader = parent;
            else {
                xmlPackageHeader = parent.SelectSingleNode("PackageHeader") as XmlElement;
            }
            if (xmlPackageHeader == null)
                throw new ArgumentException("can not find PackageHeader element");

            XmlAttribute attrVer = xmlPackageHeader.Attributes["Ver"];
            if (attrVer != null)
                this.Version = attrVer.Value;

            XmlElement xmlNamedtypes = xmlPackageHeader.SelectSingleNode("NamedTypes") as XmlElement;
            if (xmlNamedtypes != null)
            {
                XmlNodeList xmlNamedtypesNode = xmlNamedtypes.SelectNodes("Type");
                if (xmlNamedtypesNode != null && xmlNamedtypesNode.Count > 0)
                {
                    foreach (var li in xmlNamedtypesNode)
                    {
                        XmlElement Xmltype = li as XmlElement;
                        XmlAttribute attrName = Xmltype.Attributes["Name"];
                        if (attrName != null)
                        {
                            String name = attrName.Value;
                            String type = Xmltype.InnerText;
                            if (!String.IsNullOrEmpty(name) && !String.IsNullOrEmpty(type))
                                this.m_NamedTypes[name] = type;
                        }
                    }
                }
            }
        }

        public void RegisterNamedType(string name, string type)
        {
            if (!String.IsNullOrEmpty(name) && !String.IsNullOrEmpty(type))
                m_NamedTypes[name] = type;
        }

        public string getRegistedType(string name)
        {
            return m_NamedTypes[name];
        }
    }
}
